package edu.hubu.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import net.moon.jpa.model.BaseEntity;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;

import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Entity
@Table(name = "teacher_course")
//逻辑删除注解，删除sql变成了update
@SQLDelete(sql = "update teacher_course set teacher_course_is_deleted = true where teacher_course_id = ?")
//where条件带上了逻辑删除条件
@Where(clause = "teacher_course_is_deleted = false")
@ApiModel("老师课程")
@JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler", "fieldHandler"})
public class TeacherCourse extends BaseEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "snowflakeId")
    @GenericGenerator(name = "snowflakeId", strategy = "edu.hubu.commons.SnowflakeId", parameters = {@org.hibernate.annotations.Parameter(name = "prefix", value = "TEACHER-COURSE")})
    @Column(name = "teacher_course_id")
    @ApiModelProperty(value = "老师课程号", position = 1)
    private String teacherCourseId;

    @Column(name = "teacher_course_effective_date")
    @ApiModelProperty(value = "课程开课时间", position = 10)
    private Date teacherCourseEffectiveDate;

    @Column(name = "teacher_course_expiry_date")
    @ApiModelProperty(value = "课程结课时间", position = 11)
    private Date teacherCourseExpiryDate;

    @Column(name = "teacher_course_strategy")
    @ApiModelProperty(value = "老师课程安排策略，0为每周都上，1为单周，2为双周", position = 3)
    private int teacherCourseStrategy;

    @Column(name = "teacher_course_week_day")
    @ApiModelProperty(value = "老师课程上课是在周几，范围0~6", position = 4)
    private int teacherCourseWeekDay;

    @Column(name = "teacher_course_student_nums")
    @ApiModelProperty(value = "老师课程的选课人数", position = 4)
    private int teacherCourseStudentNums;

    @Column(name = "teacher_course_max_nums")
    @ApiModelProperty(value = "老师课程的最大2选课人数", position = 4)
    private int teacherCourseMaxNums;

    @Column(name = "teacher_course_is_forbidden")
    @ApiModelProperty(value = "老师课程是否被禁用", position = 6)
    private boolean teacherCourseIsForbidden = false;

    @Column(name = "teacher_course_is_deleted")
    @ApiModelProperty(value = "老师课程是否被删除", position = 7)
    private boolean teacherCourseIsDeleted = false;

    @ManyToOne(targetEntity = Course.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinColumn(name = "teacher_course_course_id", referencedColumnName = "course_id")
    @ApiModelProperty(value = "课程ID", position = 7)
    private Course course;

    @ManyToOne(targetEntity = Credit.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinColumn(name = "teacher_course_credit_id", referencedColumnName = "credit_id")
    @ApiModelProperty(value = "课程学分", position = 4)
    private Credit credit;

    @ManyToOne(targetEntity = CourseHour.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinColumn(name = "teacher_course_course_hour_id", referencedColumnName = "course_hour_id")
    @ApiModelProperty(value = "课程学时", position = 5)
    private CourseHour courseHour;

    @OneToOne(targetEntity = Book.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinColumn(name = "teacher_course_book_id", referencedColumnName = "book_id")
    @ApiModelProperty(value = "课程书籍", position = 6)
    private Book book;

    @ManyToOne(targetEntity = Major.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinColumn(name = "teacher_course_major_id", referencedColumnName = "major_id")
    @ApiModelProperty(value = "开课专业", position = 7)
    private Major major;

    @ManyToOne(targetEntity = CourseType.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinColumn(name = "teacher_course_type_id", referencedColumnName = "course_type_id")
    @ApiModelProperty(value = "课程类型", position = 9)
    private CourseType courseType;

    @ManyToMany(targetEntity = Teacher.class, cascade = {CascadeType.REFRESH, CascadeType. PERSIST}, fetch = FetchType.LAZY)
    @JoinTable(name = "teacher_teacher_course", joinColumns = {@JoinColumn(name = "teacher_teacher_course_course_id", referencedColumnName = "teacher_course_id")}, inverseJoinColumns = @JoinColumn(name = "teacher_teacher_course_user_sid", referencedColumnName = "user_sid"))
    @ApiModelProperty(value = "课程老师", position = 3)
    private List<Teacher> teachers = new ArrayList<>();

    @ManyToMany(targetEntity = CourseDailyTime.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinTable(name = "teacher_course_course_time", joinColumns = {@JoinColumn(name = "teacher_course_course_time_student_course_id", referencedColumnName = "teacher_course_id")}, inverseJoinColumns = @JoinColumn(name = "teacher_course_course_time_course_time_id", referencedColumnName = "course_time_id"))
    @ApiModelProperty(hidden = true)
    private List<CourseDailyTime> teacherCourseTime = new ArrayList<>();


    public TeacherCourse(String teacherCourseId, Date teacherCourseEffectiveDate, Date teacherCourseExpiryDate, int teacherCourseStrategy, int teacherCourseWeekDay, int teacherCourseStudentNums, int teacherCourseMaxNums, boolean teacherCourseIsForbidden, boolean teacherCourseIsDeleted, Course course, Credit credit, CourseHour courseHour, Book book, Major major, CourseType courseType, List<Teacher> teachers, List<CourseDailyTime> teacherCourseTime) {
        this.teacherCourseId = teacherCourseId;
        this.teacherCourseEffectiveDate = teacherCourseEffectiveDate;
        this.teacherCourseExpiryDate = teacherCourseExpiryDate;
        this.teacherCourseStrategy = teacherCourseStrategy;
        this.teacherCourseWeekDay = teacherCourseWeekDay;
        this.teacherCourseStudentNums = teacherCourseStudentNums;
        this.teacherCourseMaxNums = teacherCourseMaxNums;
        this.teacherCourseIsForbidden = teacherCourseIsForbidden;
        this.teacherCourseIsDeleted = teacherCourseIsDeleted;
        this.course = course;
        this.credit = credit;
        this.courseHour = courseHour;
        this.book = book;
        this.major = major;
        this.courseType = courseType;
        this.teachers = teachers;
        this.teacherCourseTime = teacherCourseTime;
    }

    public TeacherCourse() {
    }

    public static TeacherCourseBuilder builder() {
        return new TeacherCourseBuilder();
    }

    public String getTeacherCourseId() {
        return this.teacherCourseId;
    }

    public Date getTeacherCourseEffectiveDate() {
        return this.teacherCourseEffectiveDate;
    }

    public Date getTeacherCourseExpiryDate() {
        return this.teacherCourseExpiryDate;
    }

    public int getTeacherCourseStrategy() {
        return this.teacherCourseStrategy;
    }

    public int getTeacherCourseWeekDay() {
        return this.teacherCourseWeekDay;
    }

    public int getTeacherCourseStudentNums() {
        return this.teacherCourseStudentNums;
    }

    public int getTeacherCourseMaxNums() {
        return this.teacherCourseMaxNums;
    }

    public boolean isTeacherCourseIsForbidden() {
        return this.teacherCourseIsForbidden;
    }

    public boolean isTeacherCourseIsDeleted() {
        return this.teacherCourseIsDeleted;
    }

    public Course getCourse() {
        return this.course;
    }

    public Credit getCredit() {
        return this.credit;
    }

    public CourseHour getCourseHour() {
        return this.courseHour;
    }

    public Book getBook() {
        return this.book;
    }

    public Major getMajor() {
        return this.major;
    }

    public CourseType getCourseType() {
        return this.courseType;
    }

    public List<Teacher> getTeachers() {
        return this.teachers;
    }

    public List<CourseDailyTime> getTeacherCourseTime() {
        return this.teacherCourseTime;
    }

    public void setTeacherCourseId(String teacherCourseId) {
        this.teacherCourseId = teacherCourseId;
    }

    public void setTeacherCourseEffectiveDate(Date teacherCourseEffectiveDate) {
        this.teacherCourseEffectiveDate = teacherCourseEffectiveDate;
    }

    public void setTeacherCourseExpiryDate(Date teacherCourseExpiryDate) {
        this.teacherCourseExpiryDate = teacherCourseExpiryDate;
    }

    public void setTeacherCourseStrategy(int teacherCourseStrategy) {
        this.teacherCourseStrategy = teacherCourseStrategy;
    }

    public void setTeacherCourseWeekDay(int teacherCourseWeekDay) {
        this.teacherCourseWeekDay = teacherCourseWeekDay;
    }

    public void setTeacherCourseStudentNums(int teacherCourseStudentNums) {
        this.teacherCourseStudentNums = teacherCourseStudentNums;
    }

    public void setTeacherCourseMaxNums(int teacherCourseMaxNums) {
        this.teacherCourseMaxNums = teacherCourseMaxNums;
    }

    public void setTeacherCourseIsForbidden(boolean teacherCourseIsForbidden) {
        this.teacherCourseIsForbidden = teacherCourseIsForbidden;
    }

    public void setTeacherCourseIsDeleted(boolean teacherCourseIsDeleted) {
        this.teacherCourseIsDeleted = teacherCourseIsDeleted;
    }

    public void setCourse(Course course) {
        this.course = course;
    }

    public void setCredit(Credit credit) {
        this.credit = credit;
    }

    public void setCourseHour(CourseHour courseHour) {
        this.courseHour = courseHour;
    }

    public void setBook(Book book) {
        this.book = book;
    }

    public void setMajor(Major major) {
        this.major = major;
    }

    public void setCourseType(CourseType courseType) {
        this.courseType = courseType;
    }

    public void setTeachers(List<Teacher> teachers) {
        this.teachers = teachers;
    }

    public void setTeacherCourseTime(List<CourseDailyTime> teacherCourseTime) {
        this.teacherCourseTime = teacherCourseTime;
    }

    public boolean equals(final Object o) {
        if (o == this)
            return true;
        if (!(o instanceof TeacherCourse))
            return false;
        final TeacherCourse other = (TeacherCourse) o;
        if (!other.canEqual((Object) this))
            return false;
        final Object this$teacherCourseId = this.getTeacherCourseId();
        final Object other$teacherCourseId = other.getTeacherCourseId();
        if (this$teacherCourseId == null ? other$teacherCourseId != null : !this$teacherCourseId.equals(other$teacherCourseId))
            return false;
        final Object this$teacherCourseEffectiveDate = this.getTeacherCourseEffectiveDate();
        final Object other$teacherCourseEffectiveDate = other.getTeacherCourseEffectiveDate();
        if (this$teacherCourseEffectiveDate == null ? other$teacherCourseEffectiveDate != null : !this$teacherCourseEffectiveDate.equals(other$teacherCourseEffectiveDate))
            return false;
        final Object this$teacherCourseExpiryDate = this.getTeacherCourseExpiryDate();
        final Object other$teacherCourseExpiryDate = other.getTeacherCourseExpiryDate();
        if (this$teacherCourseExpiryDate == null ? other$teacherCourseExpiryDate != null : !this$teacherCourseExpiryDate.equals(other$teacherCourseExpiryDate))
            return false;
        if (this.getTeacherCourseStrategy() != other.getTeacherCourseStrategy())
            return false;
        if (this.getTeacherCourseWeekDay() != other.getTeacherCourseWeekDay())
            return false;
        if (this.getTeacherCourseStudentNums() != other.getTeacherCourseStudentNums())
            return false;
        if (this.getTeacherCourseMaxNums() != other.getTeacherCourseMaxNums())
            return false;
        if (this.isTeacherCourseIsForbidden() != other.isTeacherCourseIsForbidden())
            return false;
        if (this.isTeacherCourseIsDeleted() != other.isTeacherCourseIsDeleted())
            return false;
        final Object this$course = this.getCourse();
        final Object other$course = other.getCourse();
        if (this$course == null ? other$course != null : !this$course.equals(other$course))
            return false;
        final Object this$credit = this.getCredit();
        final Object other$credit = other.getCredit();
        if (this$credit == null ? other$credit != null : !this$credit.equals(other$credit))
            return false;
        final Object this$courseHour = this.getCourseHour();
        final Object other$courseHour = other.getCourseHour();
        if (this$courseHour == null ? other$courseHour != null : !this$courseHour.equals(other$courseHour))
            return false;
        final Object this$book = this.getBook();
        final Object other$book = other.getBook();
        if (this$book == null ? other$book != null : !this$book.equals(other$book))
            return false;
        final Object this$major = this.getMajor();
        final Object other$major = other.getMajor();
        if (this$major == null ? other$major != null : !this$major.equals(other$major))
            return false;
        final Object this$courseType = this.getCourseType();
        final Object other$courseType = other.getCourseType();
        if (this$courseType == null ? other$courseType != null : !this$courseType.equals(other$courseType))
            return false;
        final Object this$teachers = this.getTeachers();
        final Object other$teachers = other.getTeachers();
        if (this$teachers == null ? other$teachers != null : !this$teachers.equals(other$teachers))
            return false;
        final Object this$teacherCourseTime = this.getTeacherCourseTime();
        final Object other$teacherCourseTime = other.getTeacherCourseTime();
        if (this$teacherCourseTime == null ? other$teacherCourseTime != null : !this$teacherCourseTime.equals(other$teacherCourseTime))
            return false;
        return true;
    }

    protected boolean canEqual(final Object other) {
        return other instanceof TeacherCourse;
    }

    public int hashCode() {
        final int PRIME = 59;
        int result = 1;
        final Object $teacherCourseId = this.getTeacherCourseId();
        result = result * PRIME + ($teacherCourseId == null ? 43 : $teacherCourseId.hashCode());
        final Object $teacherCourseEffectiveDate = this.getTeacherCourseEffectiveDate();
        result = result * PRIME + ($teacherCourseEffectiveDate == null ? 43 : $teacherCourseEffectiveDate.hashCode());
        final Object $teacherCourseExpiryDate = this.getTeacherCourseExpiryDate();
        result = result * PRIME + ($teacherCourseExpiryDate == null ? 43 : $teacherCourseExpiryDate.hashCode());
        result = result * PRIME + this.getTeacherCourseStrategy();
        result = result * PRIME + this.getTeacherCourseWeekDay();
        result = result * PRIME + this.getTeacherCourseStudentNums();
        result = result * PRIME + this.getTeacherCourseMaxNums();
        result = result * PRIME + (this.isTeacherCourseIsForbidden() ? 79 : 97);
        result = result * PRIME + (this.isTeacherCourseIsDeleted() ? 79 : 97);
        final Object $course = this.getCourse();
        result = result * PRIME + ($course == null ? 43 : $course.hashCode());
        final Object $credit = this.getCredit();
        result = result * PRIME + ($credit == null ? 43 : $credit.hashCode());
        final Object $courseHour = this.getCourseHour();
        result = result * PRIME + ($courseHour == null ? 43 : $courseHour.hashCode());
        final Object $book = this.getBook();
        result = result * PRIME + ($book == null ? 43 : $book.hashCode());
        final Object $major = this.getMajor();
        result = result * PRIME + ($major == null ? 43 : $major.hashCode());
        final Object $courseType = this.getCourseType();
        result = result * PRIME + ($courseType == null ? 43 : $courseType.hashCode());
        final Object $teachers = this.getTeachers();
        result = result * PRIME + ($teachers == null ? 43 : $teachers.hashCode());
        final Object $teacherCourseTime = this.getTeacherCourseTime();
        result = result * PRIME + ($teacherCourseTime == null ? 43 : $teacherCourseTime.hashCode());
        return result;
    }

    public String toString() {
        return "TeacherCourse(teacherCourseId=" + this.getTeacherCourseId() + ", teacherCourseEffectiveDate=" + this.getTeacherCourseEffectiveDate() + ", teacherCourseExpiryDate=" + this.getTeacherCourseExpiryDate() + ", teacherCourseStrategy=" + this.getTeacherCourseStrategy() + ", teacherCourseWeekDay=" + this.getTeacherCourseWeekDay() + ", teacherCourseStudentNums=" + this.getTeacherCourseStudentNums() + ", teacherCourseMaxNums=" + this.getTeacherCourseMaxNums() + ", teacherCourseIsForbidden=" + this.isTeacherCourseIsForbidden() + ", teacherCourseIsDeleted=" + this.isTeacherCourseIsDeleted() + ", course=" + this.getCourse() + ", credit=" + this.getCredit() + ", courseHour=" + this.getCourseHour() + ", book=" + this.getBook() + ", major=" + this.getMajor() + ", courseType=" + this.getCourseType() + ", teachers=" + this.getTeachers() + ", teacherCourseTime=" + this.getTeacherCourseTime() + ")";
    }

    public static class TeacherCourseBuilder {
        private String teacherCourseId;
        private Date teacherCourseEffectiveDate;
        private Date teacherCourseExpiryDate;
        private int teacherCourseStrategy;
        private int teacherCourseWeekDay;
        private int teacherCourseStudentNums;
        private int teacherCourseMaxNums;
        private boolean teacherCourseIsForbidden;
        private boolean teacherCourseIsDeleted;
        private Course course;
        private Credit credit;
        private CourseHour courseHour;
        private Book book;
        private Major major;
        private CourseType courseType;
        private List<Teacher> teachers;
        private List<CourseDailyTime> teacherCourseTime;

        TeacherCourseBuilder() {
        }

        public TeacherCourseBuilder teacherCourseId(String teacherCourseId) {
            this.teacherCourseId = teacherCourseId;
            return this;
        }

        public TeacherCourseBuilder teacherCourseEffectiveDate(Date teacherCourseEffectiveDate) {
            this.teacherCourseEffectiveDate = teacherCourseEffectiveDate;
            return this;
        }

        public TeacherCourseBuilder teacherCourseExpiryDate(Date teacherCourseExpiryDate) {
            this.teacherCourseExpiryDate = teacherCourseExpiryDate;
            return this;
        }

        public TeacherCourseBuilder teacherCourseStrategy(int teacherCourseStrategy) {
            this.teacherCourseStrategy = teacherCourseStrategy;
            return this;
        }

        public TeacherCourseBuilder teacherCourseWeekDay(int teacherCourseWeekDay) {
            this.teacherCourseWeekDay = teacherCourseWeekDay;
            return this;
        }

        public TeacherCourseBuilder teacherCourseStudentNums(int teacherCourseStudentNums) {
            this.teacherCourseStudentNums = teacherCourseStudentNums;
            return this;
        }

        public TeacherCourseBuilder teacherCourseMaxNums(int teacherCourseMaxNums) {
            this.teacherCourseMaxNums = teacherCourseMaxNums;
            return this;
        }

        public TeacherCourseBuilder teacherCourseIsForbidden(boolean teacherCourseIsForbidden) {
            this.teacherCourseIsForbidden = teacherCourseIsForbidden;
            return this;
        }

        public TeacherCourseBuilder teacherCourseIsDeleted(boolean teacherCourseIsDeleted) {
            this.teacherCourseIsDeleted = teacherCourseIsDeleted;
            return this;
        }

        public TeacherCourseBuilder course(Course course) {
            this.course = course;
            return this;
        }

        public TeacherCourseBuilder credit(Credit credit) {
            this.credit = credit;
            return this;
        }

        public TeacherCourseBuilder courseHour(CourseHour courseHour) {
            this.courseHour = courseHour;
            return this;
        }

        public TeacherCourseBuilder book(Book book) {
            this.book = book;
            return this;
        }

        public TeacherCourseBuilder major(Major major) {
            this.major = major;
            return this;
        }

        public TeacherCourseBuilder courseType(CourseType courseType) {
            this.courseType = courseType;
            return this;
        }

        public TeacherCourseBuilder teachers(List<Teacher> teachers) {
            this.teachers = teachers;
            return this;
        }

        public TeacherCourseBuilder teacherCourseTime(List<CourseDailyTime> teacherCourseTime) {
            this.teacherCourseTime = teacherCourseTime;
            return this;
        }

        public TeacherCourse build() {
            return new TeacherCourse(teacherCourseId, teacherCourseEffectiveDate, teacherCourseExpiryDate, teacherCourseStrategy, teacherCourseWeekDay, teacherCourseStudentNums, teacherCourseMaxNums, teacherCourseIsForbidden, teacherCourseIsDeleted, course, credit, courseHour, book, major, courseType, teachers, teacherCourseTime);
        }

        public String toString() {
            return "TeacherCourse.TeacherCourseBuilder(teacherCourseId=" + this.teacherCourseId + ", teacherCourseEffectiveDate=" + this.teacherCourseEffectiveDate + ", teacherCourseExpiryDate=" + this.teacherCourseExpiryDate + ", teacherCourseStrategy=" + this.teacherCourseStrategy + ", teacherCourseWeekDay=" + this.teacherCourseWeekDay + ", teacherCourseStudentNums=" + this.teacherCourseStudentNums + ", teacherCourseMaxNums=" + this.teacherCourseMaxNums + ", teacherCourseIsForbidden=" + this.teacherCourseIsForbidden + ", teacherCourseIsDeleted=" + this.teacherCourseIsDeleted + ", course=" + this.course + ", credit=" + this.credit + ", courseHour=" + this.courseHour + ", book=" + this.book + ", major=" + this.major + ", courseType=" + this.courseType + ", teachers=" + this.teachers + ", teacherCourseTime=" + this.teacherCourseTime + ")";
        }
    }
}
